package jsen.tool.ddd.demo.domain.base;

import jsen.tool.ddd.adapter.infrastructure.specification.ISpecification;
import jsen.tool.ddd.adapter.infrastructure.specification.base.FilterSpecification;
import jsen.tool.ddd.adapter.infrastructure.specification.base.SpecContext;
import jsen.tool.ddd.adapter.infrastructure.strict.StrictSpecContext;

import javax.annotation.Nonnull;

/**
 * @author jsen
 * @date 2021/10/6
 */
public interface DomainObject {
    @Nonnull
    <T extends DomainObject> ISpecification<T> getStrict();

    /**
     * 限制器，每个领域对象都应该有一个限制器
     *
     * @param baseObject 原来的obj，这个会用来和现在的object diff，然后只校验其中有变更的数据
     */
    @SuppressWarnings("unchecked")
    default <T extends DomainObject> SpecContext<T> strict(T baseObject) {
        SpecContext<T> data;
        if (baseObject == null) {
            data = SpecContext.create((T) this);
        } else {
            data = StrictSpecContext.create((T) this, baseObject);
        }
        new FilterSpecification<>(getStrict()).isSatisfiedBy((SpecContext<DomainObject>) data);
        return data;
    }

}
